import base64
import datetime
import os
import time
from configparser import ConfigParser

from Crypto.Cipher import PKCS1_v1_5 as Cipher_pkcs1_v1_5
from Crypto.PublicKey import RSA

from utils.loggings import loggings

os.chdir(os.path.dirname(os.path.dirname(__file__)))

CONFIG_DIR = "config/develop_config.conf"
CONFIG = ConfigParser()
CONFIG.read(CONFIG_DIR, encoding='utf-8')


class RSAEncryptionDecryption(object):
    """
    用于解密前端的密码
    """

    public_key = CONFIG['RSA']['public_key']
    private_key = CONFIG['RSA']['private_key']
    expire_second = int(CONFIG['RSA']['expire_second'])

    # RSA加密
    @classmethod
    def encrypt(cls, message):

        # 数据类型也可以这样转换成byte
        # bytes(message, "utf-8")

        # 导入配置文件的公钥
        public_key = RSA.importKey(cls.public_key)

        # 生成对象
        cipher = Cipher_pkcs1_v1_5.new(public_key)

        # 通过生成的对象加密message明文，在python3中加密的数据必须是bytes类型的数据，不能是str类型的数据
        cipher_text = base64.b64encode(
            cipher.encrypt(f"{message}".encode("utf-8")))

        return cipher_text

    # RSA 解密
    @classmethod
    def decrypt(cls, cipher_text):
        # 导入读取到的私钥
        private_key = RSA.importKey(cls.private_key)

        # 生成对象
        cipher = Cipher_pkcs1_v1_5.new(private_key)

        try:
            # 将密文解密成明文，返回的是一个bytes类型数据，需要自己转换成str
            text = cipher.decrypt(base64.b64decode(cipher_text), "ERROR").decode("utf-8")

            return text

        except Exception as e:
            loggings.exception(1, e)
            return None

    # 增加时间戳的判断，必须在指定秒内请求
    @classmethod
    def timestamp_decrypt(cls, cipher_text):
        # 导入读取到的私钥
        private_key = RSA.importKey(cls.private_key)

        # 生成对象
        cipher = Cipher_pkcs1_v1_5.new(private_key)

        try:
            # 将密文解密成明文，返回的是一个bytes类型数据，需要自己转换成str
            text = cipher.decrypt(base64.b64decode(cipher_text), "ERROR").decode("utf-8")
            # 时间戳验证
            if int(time.mktime(time.localtime(time.time()))) - int(text[-10:]) > cls.expire_second:
                return None
            return text[0: -10]

        except Exception as e:
            loggings.exception(1, e)
            return None

    @classmethod
    def timestamp_encrypt(cls, message):
        # 导入配置文件的公钥
        public_key = RSA.importKey(cls.public_key)

        # 生成对象
        cipher = Cipher_pkcs1_v1_5.new(public_key)

        # 通过生成的对象加密message明文，在python3中加密的数据必须是bytes类型的数据，不能是str类型的数据
        cipher_text = base64.b64encode(
            cipher.encrypt(f"{message}{int(time.mktime(datetime.datetime.now().timetuple()))}".encode("utf-8")))

        return cipher_text


if __name__ == '__main__':
    # random_generator = Random.new().read
    # rsa = RSA.generate(2048, random_generator)
    # # 生成私钥
    # private_key = rsa.exportKey()
    # print(private_key.decode('utf-8'))
    # # 生成公钥
    # public_key = rsa.publickey().exportKey()
    # print(public_key.decode('utf-8'))
    # with open('rsa_private_key.pem', 'wb') as f:
    #     f.write(private_key)
    #
    # with open('rsa_public_key.pem', 'wb') as f:
    #     f.write(public_key)
    pwd = RSAEncryptionDecryption.encrypt("dw123sda5wd12s3a")
    print(pwd)
    # res = RSAEncryptionDecryption.timestamp_encrypt("user1")
    # print(res)
    # print(RSAEncryptionDecryption.timestamp_decrypt(res))